#!/usr/bin/env python3
"""
资金费率策略运行示例

演示如何配置和运行资金费率套利策略，支持合约现货对冲
"""

import sys
import os
from datetime import datetime, timedelta
from pathlib import Path

# 添加项目根目录到路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from xcquant.strategies.funding_rate_strategy import FundingRateStrategy
from xcquant.core.trading_mode import TradingModeManager, TradingConfig, TradingMode
from xcquant.core.unified_core import ConfigManager
from xcquant.core import unified_logger


def run_funding_rate_simulation():
    """运行资金费率策略模拟盘示例"""
    
    logger = unified_logger.get_logger('funding_rate_example')
    logger.info("开始运行资金费率策略模拟盘示例")
    
    try:
        # 1. 创建交易模式配置
        trading_config = TradingConfig(
            mode=TradingMode.SIMULATION,
            exchange='okx',
            initial_balance={
                'USDT': 20000.0,  # 需要更多资金进行对冲
                'BTC': 0.5,       # 初始BTC持仓
                'ETH': 2.0        # 初始ETH持仓
            },
            risk_limits={
                'max_position_ratio': 0.9,  # 资金费率策略可以使用更高仓位
                'max_drawdown': 0.05,
                'daily_loss_limit': 0.02
            }
        )
        
        # 2. 初始化交易模式管理器
        trading_manager = TradingModeManager()
        if not trading_manager.set_mode(trading_config):
            logger.error("设置交易模式失败")
            return False
        
        # 3. 配置资金费率策略参数
        strategy_config = {
            # 监控的交易对
            'symbols': ['BTC-USDT', 'ETH-USDT', 'SOL-USDT'],
            
            # 资金费率阈值
            'min_funding_rate': 0.0001,    # 最小资金费率 0.01%
            'max_funding_rate': 0.01,      # 最大资金费率 1%
            'funding_threshold': 0.0005,   # 开仓阈值 0.05%
            'close_threshold': 0.0001,     # 平仓阈值 0.01%
            
            # 仓位管理
            'max_position_per_symbol': 5000.0,  # 每个币种最大仓位 (USDT)
            'position_ratio': 0.8,              # 仓位比例
            'hedge_ratio': 1.0,                 # 对冲比例 100%
            
            # 风险控制
            'stop_loss_percent': 0.02,     # 止损 2%
            'max_holding_hours': 8,        # 最大持仓时间 8小时
            'max_positions': 3,            # 最大同时持仓数
            
            # 对冲设置
            'enable_hedge': True,          # 启用对冲
            'hedge_delay_seconds': 5,      # 对冲延迟 5秒
            'rebalance_threshold': 0.05,   # 再平衡阈值 5%
            
            # 交易所配置
            'exchange': 'okx',
            'spot_account': 'trading',     # 现货账户
            'futures_account': 'futures'   # 合约账户
        }
        
        # 4. 创建资金费率策略实例
        strategy = FundingRateStrategy(strategy_config)
        
        # 5. 设置策略的管理器
        strategy.set_order_manager(trading_manager.get_order_manager())
        strategy.set_account_manager(trading_manager.get_account_manager())
        
        # 6. 验证策略配置
        if not trading_manager.validate_strategy_config(strategy_config):
            logger.error("策略配置验证失败")
            return False
        
        # 7. 初始化策略
        logger.info("初始化资金费率策略...")
        if not strategy.initialize():
            logger.error("策略初始化失败")
            return False
        
        logger.info("资金费率策略初始化成功")
        logger.info(f"监控交易对: {strategy_config['symbols']}")
        logger.info(f"资金费率阈值: {strategy_config['funding_threshold']:.4%}")
        
        # 8. 模拟运行策略
        logger.info("开始模拟运行策略...")
        
        # 模拟资金费率数据
        import random
        
        for i in range(50):  # 模拟50个周期
            logger.info(f"\n=== 周期 {i+1} ===")
            
            # 为每个交易对生成模拟数据
            for symbol in strategy_config['symbols']:
                # 生成随机资金费率 (-0.1% 到 0.1%)
                funding_rate = random.uniform(-0.001, 0.001)
                
                # 生成价格数据
                base_prices = {'BTC-USDT': 42000, 'ETH-USDT': 2500, 'SOL-USDT': 100}
                base_price = base_prices.get(symbol, 1000)
                spot_price = base_price * (1 + random.uniform(-0.01, 0.01))
                futures_price = spot_price * (1 + random.uniform(-0.0005, 0.0005))
                
                # 更新资金费率
                strategy.update_funding_rate(symbol, funding_rate, datetime.now())
                
                # 模拟市场数据
                market_data = {
                    'symbol': symbol,
                    'spot_price': spot_price,
                    'futures_price': futures_price,
                    'funding_rate': funding_rate,
                    'timestamp': datetime.now(),
                    'volume_24h': random.uniform(1000000, 10000000)
                }
                
                # 调用策略
                try:
                    strategy.on_tick(symbol, market_data)
                except Exception as e:
                    logger.error(f"策略执行错误 {symbol}: {e}")
                    continue
                
                # 显示资金费率信息
                if abs(funding_rate) > strategy_config['funding_threshold']:
                    logger.info(f"{symbol}: 资金费率={funding_rate:.4%} ({'正' if funding_rate > 0 else '负'})")
                    logger.info(f"  现货价格: {spot_price:.2f}, 合约价格: {futures_price:.2f}")
            
            # 检查交易机会
            opportunities = strategy.check_opportunities()
            if opportunities:
                logger.info(f"发现 {len(opportunities)} 个交易机会")
                for opp in opportunities:
                    logger.info(f"  {opp['symbol']}: {opp['action']} (资金费率: {opp['funding_rate']:.4%})")
            
            # 显示当前持仓
            positions = strategy.get_current_positions()
            if positions:
                logger.info("当前持仓:")
                for pos in positions:
                    logger.info(f"  {pos['symbol']}: {pos['side']} {pos['size']:.4f} (PnL: {pos.get('unrealized_pnl', 0):.2f})")
            
            # 模拟时间间隔
            import time
            time.sleep(0.1)  # 短暂延迟
        
        # 9. 显示策略统计
        stats = strategy.get_strategy_stats()
        logger.info("\n=== 策略统计 ===")
        logger.info(f"总交易次数: {stats.get('total_trades', 0)}")
        logger.info(f"盈利交易: {stats.get('profitable_trades', 0)}")
        logger.info(f"亏损交易: {stats.get('losing_trades', 0)}")
        logger.info(f"总盈亏: {stats.get('total_pnl', 0):.2f} USDT")
        logger.info(f"资金费率收入: {stats.get('funding_income', 0):.2f} USDT")
        logger.info(f"平均持仓时间: {stats.get('avg_holding_time', 0):.1f} 小时")
        
        logger.info("资金费率策略模拟运行完成")
        return True
        
    except Exception as e:
        logger.error(f"运行资金费率策略失败: {e}")
        return False
    
    finally:
        # 清理资源
        if 'trading_manager' in locals():
            trading_manager.shutdown()


def run_funding_rate_backtest():
    """运行资金费率策略回测示例"""
    
    logger = unified_logger.get_logger('funding_backtest_example')
    logger.info("开始运行资金费率策略回测示例")
    
    try:
        from xcquant.backtesting.backtest_engine import BacktestEngine
        
        # 1. 配置回测参数
        backtest_config = {
            'start_date': '2024-01-01',
            'end_date': '2024-02-01',
            'initial_balance': {'USDT': 50000.0},  # 资金费率策略需要更多资金
            'commission_rate': 0.0002,  # 0.02% 手续费 (Maker)
            'slippage': 0.0001         # 0.01% 滑点
        }
        
        # 2. 创建回测引擎
        backtest_engine = BacktestEngine(backtest_config)
        
        # 3. 配置资金费率策略
        strategy_config = {
            'symbols': ['BTC-USDT', 'ETH-USDT'],
            
            # 回测专用参数
            'funding_threshold': 0.0003,   # 降低阈值以增加交易机会
            'close_threshold': 0.0001,
            'max_position_per_symbol': 10000.0,
            'position_ratio': 0.9,
            'hedge_ratio': 1.0,
            
            # 风险控制
            'stop_loss_percent': 0.015,
            'max_holding_hours': 12,
            'max_positions': 2,
            
            'enable_hedge': True,
            'exchange': 'okx'
        }
        
        # 4. 创建策略实例
        strategy = FundingRateStrategy(strategy_config)
        backtest_engine.set_strategy(strategy)
        
        # 5. 加载多个交易对的数据
        logger.info("加载回测数据...")
        
        all_data = {}
        for symbol in strategy_config['symbols']:
            # 加载现货数据
            spot_data = backtest_engine.load_data(
                exchange='okx',
                symbol=symbol,
                interval='1h',
                trade_type='spot'
            )
            
            # 加载合约数据
            futures_data = backtest_engine.load_data(
                exchange='okx',
                symbol=symbol,
                interval='1h',
                trade_type='futures'
            )
            
            if spot_data.empty or futures_data.empty:
                logger.warning(f"{symbol} 数据不完整，跳过")
                continue
            
            all_data[symbol] = {
                'spot': spot_data,
                'futures': futures_data
            }
            
            logger.info(f"{symbol}: 现货 {len(spot_data)} 条, 合约 {len(futures_data)} 条")
        
        if not all_data:
            logger.error("没有可用的回测数据")
            return False
        
        # 6. 运行回测 (使用第一个交易对的数据作为主时间轴)
        main_symbol = list(all_data.keys())[0]
        main_data = all_data[main_symbol]['futures']  # 使用合约数据作为主时间轴
        
        logger.info("开始回测...")
        results = backtest_engine.run_backtest(main_data, main_symbol)
        
        if not results:
            logger.error("回测失败")
            return False
        
        # 7. 生成回测报告
        logger.info("回测完成，生成报告...")
        
        report_path = backtest_engine.generate_report('./funding_backtest_results')
        logger.info(f"回测报告已生成: {report_path}")
        
        # 绘制结果图表
        backtest_engine.plot_results('./funding_backtest_results')
        logger.info("回测图表已生成")
        
        # 显示关键指标
        metrics = results.get('metrics', {})
        logger.info("\n=== 资金费率策略回测结果 ===")
        logger.info(f"总收益率: {metrics.get('total_return', 0):.2%}")
        logger.info(f"年化收益率: {metrics.get('annual_return', 0):.2%}")
        logger.info(f"最大回撤: {metrics.get('max_drawdown', 0):.2%}")
        logger.info(f"夏普比率: {metrics.get('sharpe_ratio', 0):.2f}")
        logger.info(f"交易次数: {metrics.get('total_trades', 0)}")
        logger.info(f"胜率: {metrics.get('win_rate', 0):.2%}")
        logger.info(f"平均持仓时间: {metrics.get('avg_holding_time', 0):.1f} 小时")
        
        # 资金费率特有指标
        funding_metrics = results.get('funding_metrics', {})
        if funding_metrics:
            logger.info(f"资金费率收入: {funding_metrics.get('total_funding_income', 0):.2f} USDT")
            logger.info(f"对冲成本: {funding_metrics.get('hedge_cost', 0):.2f} USDT")
            logger.info(f"净资金费率收益: {funding_metrics.get('net_funding_profit', 0):.2f} USDT")
        
        return True
        
    except Exception as e:
        logger.error(f"回测失败: {e}")
        return False


def monitor_funding_rates():
    """实时监控资金费率"""
    
    logger = unified_logger.get_logger('funding_monitor')
    logger.info("开始监控资金费率")
    
    try:
        from xcquant.data.data_manager import DataManager
        
        # 创建数据管理器
        data_manager = DataManager({})
        
        symbols = ['BTC-USDT', 'ETH-USDT', 'SOL-USDT', 'ADA-USDT', 'DOT-USDT']
        
        logger.info("实时监控资金费率 (按 Ctrl+C 退出)")
        logger.info("=" * 60)
        
        while True:
            print(f"\n{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - 资金费率监控")
            print("-" * 60)
            
            for symbol in symbols:
                try:
                    # 这里应该调用实际的API获取资金费率
                    # 现在使用模拟数据
                    import random
                    funding_rate = random.uniform(-0.001, 0.001)
                    next_funding_time = datetime.now() + timedelta(hours=8)
                    
                    # 获取当前价格
                    price = data_manager.get_latest_price('okx', symbol)
                    if not price:
                        price = random.uniform(1000, 50000)  # 模拟价格
                    
                    # 显示信息
                    status = "🔴 做空机会" if funding_rate > 0.0005 else "🟢 做多机会" if funding_rate < -0.0005 else "⚪ 观望"
                    
                    print(f"{symbol:12} | 费率: {funding_rate:+.4%} | 价格: {price:>10.2f} | {status}")
                    
                except Exception as e:
                    print(f"{symbol:12} | 获取数据失败: {e}")
            
            print(f"\n下次资金费率结算: {next_funding_time.strftime('%H:%M:%S')}")
            print("=" * 60)
            
            # 等待30秒
            import time
            time.sleep(30)
            
    except KeyboardInterrupt:
        logger.info("\n监控已停止")
    except Exception as e:
        logger.error(f"监控失败: {e}")


def main():
    """主函数"""
    print("XCQuant 资金费率策略示例")
    print("=" * 50)
    print("1. 模拟盘交易示例")
    print("2. 回测示例")
    print("3. 实时监控资金费率")
    print("4. 退出")
    
    while True:
        try:
            choice = input("\n请选择运行模式 (1-4): ").strip()
            
            if choice == '1':
                print("\n运行模拟盘交易示例...")
                success = run_funding_rate_simulation()
                if success:
                    print("✅ 模拟盘交易示例运行成功")
                else:
                    print("❌ 模拟盘交易示例运行失败")
                    
            elif choice == '2':
                print("\n运行回测示例...")
                success = run_funding_rate_backtest()
                if success:
                    print("✅ 回测示例运行成功")
                else:
                    print("❌ 回测示例运行失败")
                    
            elif choice == '3':
                print("\n开始实时监控资金费率...")
                monitor_funding_rates()
                    
            elif choice == '4':
                print("退出程序")
                break
                
            else:
                print("无效选择，请输入 1-4")
                
        except KeyboardInterrupt:
            print("\n\n程序被用户中断")
            break
        except Exception as e:
            print(f"运行错误: {e}")


if __name__ == '__main__':
    main()